import asyncio

import aiohttp
import grequests
import pyapollo
import requests
import json


# 服务
class Service(object):
    id = None

    def __init__(self, host, port, name):
        self.host = host
        self.port = port
        self.name = name
        self.id = self.name + "-" + str.replace(self.host, ".", "-", 10)

    def build_json(self):
        return {
            "id": self.id,
            "name": self.name,
            "tags": [
                "secure=false"
            ],
            "address": self.host,
            "port": self.port,
            "checks": [
                {
                    "interval": "10s",
                    "http": "http://" + self.host + ":" + str(self.port) + "/actuator/health",
                    "timeout": "1s"
                }
            ]
        }


consul_url = "http://localhost:8500"
register_url = consul_url + "/v1/agent/service/register"
dis_register_url = consul_url + "/v1/agent/service/deregister/"
server_map = {"201947720": ["kguser", "kggateway", "xxl-admin", "xxl-executor"],
              "201947721": ["kgms", "kgsdk", "kg-services-edit", "kg-services-public", "kg-services-semantic"]}


class ServiceInfo(object):
    def __init__(self, port, status):
        self.port = port
        self.status = status


def exception_handler(request, exception): print("Request failed")


# 把服务注册到consul
def batch_register(service_arr):
    reqs = []
    for ser in service_arr:
        reqs.append(grequests.put(register_url, json=ser.build_json(), timeout=0.5))
    grequests.map(reqs, exception_handler=exception_handler)


# consul取消注册
def batch_dis_register(server_ids):
    reqs = []
    for ser in server_ids:
        print(dis_register_url + ser)
        reqs.append(grequests.put(dis_register_url + ser, timeout=0.5))
    grequests.map(reqs, exception_handler=exception_handler)


# 健康检测
def health_check(register_host, service_name):
    resisted = "critical"
    is_health = "critical"
    try:

        health = requests.get("http://" + register_host + ":8500" + "/v1/health/service/" + service_name, timeout=0.5)

        for check in json.loads(health.__getattribute__("content"))[0].get("Checks"):
            if check.get("Name") == "Serf Health Status":
                resisted = check.get("Status")
            if check.get("CheckID") == "serfHealth":
                is_health = check.get("Status")
    except Exception:
        pass
    return resisted + "：" + is_health


def all_service(apollo_url, register_host):
    service_map = {}
    for val in server_map.items():
        app = pyapollo.ApolloClient(app_id=val[0], config_server_url=apollo_url)
        app.start()
        for service in val[1]:
            port = app.get_value(key="server.port", namespace=service, default_val="8080")
            service_map.__setitem__(service, ServiceInfo(port=int(port), status=health_check(register_host, service)))
        app.stop()
    return service_map


def res(services_map, service_port_map, host_addr):
    opt(services_map, service_port_map, host_addr, "true")


def deres(services_map, service_port_map, host_addr):
    opt(services_map, service_port_map, host_addr, "false")


def opt(services_map, service_port_map, host_addr, is_res):
    register_arr = []
    dis_register_arr = []
    for service in services_map.items():
        if service[1].get() == 1:
            service_ins = Service(str(host_addr.get()), service_port_map.get(service[0]).port,
                                  service[0])
            if is_res == "true":
                print("尝试注册：%s" % service_ins.id)
                register_arr.append(service_ins)
            else:
                print("尝试注销：%s" % service_ins.id)
                dis_register_arr.append(service_ins.id)
    if len(register_arr) > 0:
        batch_register(register_arr)
    if len(dis_register_arr) > 0:
        batch_dis_register(dis_register_arr)
# if __name__ == '__main__':
#     for aa in all_service().items():
#         print(aa)
# kguser = Service("192.168.4.31", server_map.get("kguser"), "kguser")
# print(register(kguser))
# print(dis_register(kguser.id))
